home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1994 / MacHack 1994.toast / MacHack™94 / Miscellaneous / Randy Thelen / ThreadedBrot / Lib / AppLib.cp < prev    next >
Encoding:
Text File  |  1994-06-26  |  9.1 KB  |  436 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        AppLib.cp
  3.  
  4.     Contains:    The “guts” of a Macintosh application.
  5.  
  6.     Written by: Dave Falkenburg
  7.  
  8.     Copyright:    © 1993-94 by Dave Falkenburg, all rights reserved.
  9.  
  10.     Change History (most recent first):
  11.      
  12.  */
  13.  
  14. #ifdef    SystemSevenOrLater
  15. #undef    SystemSevenOrLater
  16. #endif
  17. #define    SystemSevenOrLater    1
  18.  
  19. #include <limits.h>        //    For LONG_MAX
  20.  
  21. #include <Types.h>
  22. #include <Quickdraw.h>
  23. #include <Fonts.h>
  24. #include <Menus.h>
  25. #include <Windows.h>
  26. #include <Dialogs.h>
  27. #include <Desk.h>
  28. #include <Events.h>
  29. #include <AppleEvents.h>
  30. #include <DiskInit.h>
  31. #include <GestaltEqu.h>
  32. #include <ToolUtils.h>
  33. #include <Traps.h>
  34. #include <LowMem.h>
  35.  
  36. #include <Threads.h>
  37. #include <Drag.h>
  38. #include <Editions.h>
  39. #include <OCEStandardMail.h>
  40.  
  41. #include <TextServices.h>
  42. #if    0
  43. #include <TSMTE.h>
  44. #endif
  45.  
  46. #include "AppLib.h"
  47. #include "Window.h"
  48. #include "OCEStandardMail.h"
  49. #include "AppleEventHandling.h"
  50.  
  51.  
  52. //    Function Prototypes
  53.  
  54. void    main(void);
  55. void    MainEventLoop(void);
  56.  
  57. void    HandleMouseDown(TWindow * topWindowObj, EventRecord * anEvent);
  58. void    HandleUpdate(EventRecord * anEvent);
  59. void    HandleClose(WindowPtr aWindow);
  60.  
  61.  
  62.  
  63. //    Globals
  64.  
  65. Boolean    gDone = false;
  66. Boolean    gMenuBarNeedsUpdate = true;
  67.  
  68. Boolean    gHasColorQuickdraw = false;
  69. Boolean    gHasThreadManager = false;
  70. Boolean    gHasDragManager = false;
  71. Boolean    gHasAppleScript = false;
  72. Boolean    gHasAOCE = false;
  73. Boolean    gHasDisplayManager = false;
  74. Boolean    gHasTextServices = false;
  75. Boolean    gHasTSMTE = false;
  76.  
  77.  
  78. GrafPtr    gWindowManagerPort;
  79. Rect    gDeskRectangle;
  80.  
  81.  
  82. //    FrontWindow custom procedure for AOCE standard mail package:
  83. //        It enables some of AOCE to cleanly with “Dean Yu”-style floating windows
  84.  
  85. pascal    WindowPtr
  86. FrontWindowProcForAOCE(long /* unusedParam */)
  87.     {
  88.     return FrontNonFloatingWindow();
  89.     }
  90.  
  91. FrontWindowUPP FrontWindowProcForAOCEUPP = NewFrontWindowProc(&FrontWindowProcForAOCE);
  92.  
  93.  
  94.  
  95. //    Values that can be adjusted by other application code to change
  96. //    the behavior of the MainEventLoop.
  97. //
  98. //    Rules of thumb:
  99. //
  100. //        Increase gXXXRunQuantum (and decrease gXXXSleepQuantum) when:
  101. //            The application has many threads running that need time
  102. //
  103. //        Decrease gXXXRunQuantum when:
  104. //            Sending AppleEvents to other applications
  105. //            Launching other applications
  106. //            Running in the background
  107.  
  108. unsigned long    gForegroundRunQuantum = 0;
  109. unsigned long    gForegroundSleepQuantum = GetCaretTime();
  110. unsigned long    gBackgroundRunQuantum = 0;
  111. unsigned long    gBackgroundSleepQuantum = LONG_MAX;
  112.  
  113.  
  114. //    Globals used to “tune” the performance of MainEventLoop
  115. //    (assume we’ll be starting in the foreground)
  116.  
  117. static    unsigned long    gRunQuantum = gForegroundRunQuantum;
  118. static    unsigned long    gSleepQuantum = gForegroundSleepQuantum;
  119.  
  120. RgnHandle        gMouseRegion = nil;
  121.  
  122.  
  123.  
  124. #ifndef    __MWERKS__
  125. QDGlobals    qd;
  126. #endif
  127.  
  128. void
  129. main(void)
  130.     {
  131.     long    feature;
  132.  
  133.     MaxApplZone();
  134.     MoreMasters();
  135.     MoreMasters();
  136.     MoreMasters();
  137.     MoreMasters();
  138.  
  139.     InitGraf(&qd.thePort);    
  140.     InitFonts();
  141.     InitWindows();
  142.     InitMenus();
  143.     TEInit();
  144.     InitDialogs(nil);
  145.  
  146.     if (GetToolTrapAddress(_Unimplemented) == GetOSTrapAddress(_Gestalt))
  147.         FatalErrorAlert(kCoreErrorStrings,kUnsupportedSystemSoftware);
  148.  
  149.     if (Gestalt(gestaltQuickdrawFeatures,&feature) == noErr)
  150.         gHasColorQuickdraw = ((feature & (1 << gestaltHasColor)) != 0);
  151.     
  152.     if ((Gestalt(gestaltAppleEventsAttr,&feature) == noErr) &&
  153.         (feature & (1 << gestaltAppleEventsPresent)))
  154.         {
  155.         //    Figure out if we need to do AppleEvent recording
  156.         gHasAppleScript = (feature & (1 << gestaltScriptingSupport));
  157.         }
  158.     else
  159.         FatalErrorAlert(kCoreErrorStrings,kUnsupportedSystemSoftware);
  160.  
  161.     if ((Gestalt(gestaltTSMgrVersion,&feature) == noErr) && (feature >= 1))
  162.         {
  163.         gHasTextServices = true;
  164. #if    0
  165.         if (Gestalt(gestaltTSMTEAttr, &feature) == noErr)
  166.             gHasTSMTE = (feature & (1 << gestaltTSMTEPresent));
  167. #endif
  168.         }
  169.  
  170.     if (Gestalt(gestaltThreadMgrAttr,&feature) == noErr)
  171.         {
  172. #if    powerc
  173.         //    If running on a PowerPC, make sure that we not only have the
  174.         //    68K Thread Manager, but also the PowerPC shared library, too.
  175.         gHasThreadManager = ((feature & ((1 << gestaltThreadMgrPresent) | (1 << gestaltThreadsLibraryPresent))) != 0);
  176. #else
  177.         gHasThreadManager = ((feature & (1 << gestaltThreadMgrPresent)) != 0);
  178. #endif
  179.         }
  180.     
  181.     if (gHasThreadManager == false)
  182.         FatalErrorAlert(kCoreErrorStrings,kNeedsThreadManager);
  183.         
  184.     
  185.     if (Gestalt(gestaltDragMgrAttr,&feature) == noErr)
  186.         {
  187. #if    powerc
  188.         //    If running on a PowerPC, make sure that we not only have the
  189.         //    68K Drag Manager, but also the PowerPC shared library, too.
  190.         gHasDragManager = ((feature & ((1 << gestaltDragMgrPresent) | (1 << gestaltPPCDragLibPresent))) != 0);
  191. #else
  192.         gHasDragManager = ((feature & (1 << gestaltDragMgrPresent)) != 0);
  193. #endif
  194.  
  195.         if (gHasDragManager)
  196.             {
  197.             InstallTrackingHandler(NewDragTrackingHandlerProc(CallWindowDragTrackingHandler),(WindowPtr) nil,nil);
  198.             InstallReceiveHandler(NewDragReceiveHandlerProc(CallWindowDragReceiveHandler),(WindowPtr) nil,nil);
  199.             }
  200.         }
  201.  
  202.     if (Gestalt(gestaltDisplayMgrAttr,&feature) == noErr)
  203.         gHasDisplayManager = ((feature & (1 << gestaltDisplayMgrPresent)) != 0);
  204.     
  205.     //    Check for and initialize AOCE Standard Mail package if it exists
  206.     
  207.     if ((Gestalt(gestaltSMPMailerVersion,&feature) == noErr) && (feature != 0))
  208.         {
  209.         gHasAOCE = (SMPInitMailer(kSMPVersion) == noErr);
  210.         }
  211.  
  212.     InstallAppleEventHandlers();
  213.             
  214.     GetWMgrPort(&gWindowManagerPort);
  215.     gDeskRectangle = (**GetGrayRgn()).rgnBBox;
  216.     
  217.     if (SetupApplication() == noErr)
  218.         MainEventLoop();
  219.     }
  220.  
  221.  
  222.  
  223.  
  224. void
  225. MainEventLoop(void)
  226.     {
  227.     EventRecord        anEvent;
  228.     unsigned long    nextTimeToCheckForEvents = 0;
  229.     
  230.     while (!gDone)
  231.         {
  232.         if (gMenuBarNeedsUpdate)
  233.             {
  234.             gMenuBarNeedsUpdate = false;
  235.             DrawMenuBar();
  236.             }
  237.             
  238.         if ((gRunQuantum == 0) ||
  239.             (TickCount() > nextTimeToCheckForEvents))
  240.             {
  241.             nextTimeToCheckForEvents = TickCount() + gRunQuantum;
  242.             
  243.             (void) WaitNextEvent(everyEvent,&anEvent,gSleepQuantum,gMouseRegion);
  244.                         
  245.             HandleEvent(&anEvent);
  246.             }
  247.  
  248.         if (gHasThreadManager)
  249.             YieldToAnyThread();
  250.         }
  251.     }
  252.  
  253.  
  254. void
  255. HandleEvent(EventRecord *anEvent)
  256.     {
  257.     TWindow    *wobj = GetWindowObject(FrontNonFloatingWindow());
  258.  
  259.     if (gHasAOCE)
  260.         {
  261.         SMPMailerResult    whatHappened;
  262.         OSErr            err    = SMPMailerEvent(anEvent,&whatHappened,FrontWindowProcForAOCEUPP,0);
  263.  
  264.         //    Deal with PowerTalk Standard Mail stuff here!
  265.         
  266.         }
  267.         
  268.     if (wobj != nil)
  269.         wobj->AdjustCursor(anEvent);
  270.     
  271.     if ((wobj != nil) && wobj->EventFilter(anEvent))
  272.         {
  273.         return;
  274.         }
  275.     else switch (anEvent->what)
  276.         {
  277.         case    nullEvent:
  278.             break;
  279.             
  280.         case    mouseDown:
  281.             HandleMouseDown(wobj,anEvent);
  282.             break;
  283.         
  284.         case    keyDown:
  285.         case    autoKey:
  286.             if (anEvent->modifiers & cmdKey)
  287.                 HandleMenu(wobj,MenuKey((short) anEvent->message & charCodeMask));
  288.             else if (wobj != nil)
  289.                 wobj->KeyDown(anEvent);
  290.             break;
  291.             
  292.         case    updateEvt:
  293.             HandleUpdate(anEvent);
  294.             break;
  295.             
  296.         case diskEvt:
  297.             if (anEvent->message >> 16)
  298.                 {
  299.                 static    Point    where = {50,50};
  300.                 (void) DIBadMount(where,anEvent->message);
  301.                 }
  302.             break;
  303.                 
  304.         case    osEvt:
  305.             switch ((anEvent->message & osEvtMessageMask) >> 24)
  306.                 {
  307.                 case    mouseMovedMessage:
  308.                     break;
  309.                     
  310.                 case    suspendResumeMessage:                    
  311.                     if (anEvent->message & resumeFlag)
  312.                         {
  313.                         gRunQuantum = gForegroundRunQuantum;
  314.                         gSleepQuantum = gForegroundSleepQuantum;
  315.                         }
  316.                     else
  317.                         {
  318.                         gRunQuantum = gBackgroundRunQuantum;
  319.                         gSleepQuantum = gBackgroundSleepQuantum;
  320.                         }
  321.  
  322.                     SuspendResumeWindows((anEvent->message & resumeFlag) != 0);
  323.                     if (anEvent->message & convertClipboardFlag)
  324.                         ConvertClipboard();
  325.                     break;
  326.                 }
  327.             break;
  328.         
  329.         case    kHighLevelEvent:
  330.             (void) AEProcessAppleEvent(anEvent);
  331.             break;
  332.             
  333.         default:
  334.             break;
  335.         }
  336.     }
  337.  
  338. void
  339. HandleMouseDown(TWindow * topWindowObj,EventRecord *anEvent)
  340.     {
  341.     WindowPtr    aWindow;
  342.     short        partCode;
  343.     TWindow        *wobj;
  344.  
  345.     partCode = FindWindow(anEvent->where,&aWindow);
  346.     wobj = GetWindowObject(aWindow);
  347.     switch(partCode)
  348.         {
  349.         case    inMenuBar:
  350.             HandleMenu(topWindowObj,MenuSelect(anEvent->where));
  351.             break;
  352.             
  353.         case    inSysWindow:
  354.             SystemClick(anEvent,aWindow);
  355.             break;
  356.             
  357.         case    inContent:
  358.             if (wobj)
  359.                 {
  360.                 GrafPtr    oldPort;
  361.                 
  362.                 GetPort(&oldPort);
  363.                 SetPort(aWindow);
  364.                 GlobalToLocal(&anEvent->where);
  365.                 wobj->Click(anEvent);
  366.                 SetPort(aWindow);
  367.                 }
  368.             break;
  369.             
  370.         case    inDrag:
  371.             if (wobj)
  372.                 wobj->Drag(anEvent->where);
  373.             break;
  374.             
  375.         case    inGrow:
  376.             if (wobj)
  377.                 wobj->Grow(anEvent->where);
  378.             break;
  379.             
  380.         case    inGoAway:
  381.             if (TrackGoAway(aWindow,anEvent->where))
  382.                 HandleClose(aWindow);
  383.             break;
  384.  
  385.         case    inZoomIn:
  386.         case    inZoomOut:
  387.             if (TrackBox(aWindow,anEvent->where,partCode) && (wobj))
  388.                 wobj->Zoom(partCode);
  389.             break;
  390.             
  391.         default:
  392.             break;
  393.         }
  394.     }
  395.     
  396.  
  397. void    HandleUpdate(EventRecord * anEvent)
  398.     {
  399.     GrafPtr        oldPort;
  400.     WindowPtr    aWindow = (WindowPtr) anEvent->message;    
  401.     TWindow    *    wobj;
  402.         
  403.     GetPort(&oldPort);
  404.     SetPort(aWindow);
  405.     BeginUpdate(aWindow);
  406.     
  407.     if ((wobj = GetWindowObject(aWindow)) != nil)
  408.         wobj->Draw();
  409.     
  410.     EndUpdate(aWindow);
  411.     SetPort(oldPort);
  412.     }
  413.  
  414. void
  415. HandleClose(WindowPtr aWindow)
  416.     {
  417.     short    windowKind;
  418.     TWindow    *wobj;
  419.     
  420.     if (aWindow)
  421.         {
  422.         windowKind = ((WindowPeek) aWindow)->windowKind;
  423.         if (windowKind < 0)
  424.             {
  425.             CloseDeskAcc(((WindowPeek)aWindow)->windowKind);
  426.             }
  427.         else if ( ((wobj = GetWindowObject(aWindow)) != nil) &&
  428.                     wobj->CanClose() &&
  429.                     wobj->Close() &&
  430.                     wobj->DeleteAfterClose())
  431.             {
  432.             delete wobj;
  433.             }
  434.         }
  435.     }
  436.